﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dos.ORM;
using Finance.IDal;
using Finance.Poco;
using Finance.Entity;

namespace Finance.Dal
{
    public class UserDal : BaseDal, IUserDal
    {
        public UserEntity GetUser(object providerUserKey, bool userIsOnline)
        {
            return ToEntity(dbSession.From<User>().Where(user => user.ProviderUserKey == providerUserKey).First());
        }

        public bool ChangePassword(string username, string oldPasswordEnc, string newPasswordEnc)
        {
            return dbSession.Update<User>(User._.Password, newPasswordEnc, user => user.UserName == username && user.Password == oldPasswordEnc) > 0;
        }

        //public bool CreateUser(string username, string passwordEnc, string email, string passwordQuestion, string passwordAnswer, bool isApproved)
        //{
        //   return  this.CreateUser(username, passwordEnc, email, passwordQuestion, passwordAnswer, isApproved, Guid.NewGuid().ToString());
        //}

        public bool CreateUser(string username, string passwordEnc, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, int orgId)
        {
            if (providerUserKey == null)
                throw new ArgumentNullException("providerUserKey");

            User user = new User();
            user.UserName = username;
            user.Password = passwordEnc;
            user.Email = email;
            user.PasswordQuestion = passwordQuestion;
            user.PasswordAnswer = passwordAnswer;
            user.IsApproved = isApproved ? 1 : 0;
            user.ProviderUserKey = providerUserKey as string;
            user.OrgId = orgId;

            return dbSession.Insert<User>(user) > 0;
        }

        private UserEntity ToEntity(User user)
        {
            if (user != null)
            {
                return new UserEntity
                {
                    Id = user.Id,
                    CreateTime = user.CreateTime,
                    CreateUserName = user.CreateUserName,
                    Email = user.Email,
                    IsApproved = user.IsApproved,
                    IsEnable = user.IsEnable,
                    LastLoginIP = user.LastLoginIP,
                    LastLoginTime = user.LastLoginTime,
                    OrgId = user.OrgId,
                    Password = user.Password,
                    PasswordAnswer = user.PasswordAnswer,
                    PasswordQuestion = user.PasswordQuestion,
                    Post = user.Post,
                    ProviderUserKey = user.ProviderUserKey,
                    UserName = user.UserName,

                };
            }
            return null;
        }


        public bool ValidateUser(string username, string passwordEnc)
        {
            return dbSession.Exists<User>(user => user.UserName == username && user.Password == passwordEnc);
        }

        public string GetUserNameByEmail(string email)
        {
            var userPoco = dbSession.From<User>().Where(user => user.Email == email).Select(user => user.UserName).ToFirstDefault();
            if (userPoco != null)
                return userPoco.UserName;
            else
                return null;
        }

        public bool ResetPassword(string username, string answer, string newPasswordEnc)
        {
            return dbSession.Update<User>(User._.Password, newPasswordEnc, u => u.UserName == username && u.PasswordAnswer == answer) > 0;//.Where(u=>u.UserName==username&&u.PasswordAnswer==answer)
        }

        public bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }

        public void UpdateUser(UserEntity userEntity)
        {
            var user = dbSession.From<User>().Where(u => u.ProviderUserKey == userEntity.ProviderUserKey).ToFirst();
            if (user != null)
            {
                user.Attach(EntityState.Modified);
                user.Email = userEntity.Email;
                user.IsApproved = userEntity.IsApproved;
                user.LastLoginTime = userEntity.LastLoginTime;
                user.PasswordQuestion = userEntity.PasswordQuestion;
                user.ProviderUserKey = userEntity.ProviderUserKey;
                dbSession.Save(user);
            }
        }


        public bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            return dbSession.Delete<User>(u => u.UserName == username) > 0;
        }


        public IEnumerable<ViewUserEntity> List(string userName, int pageIndex, int pageSize, out int total)
        {
            var sql = dbSession.From<ViewUser>();
            if (!string.IsNullOrWhiteSpace(userName))
            {
                sql.Where(user => user.UserName.Like(userName));
            }
            total = sql.Count();
            var userList = sql.Page(pageSize, pageIndex).ToList();
            return userList.Select(AutoMapper.Mapper.Map<ViewUserEntity>).ToList();
        }

        public bool ResetPassword(string userName, string passwordEnc)
        {
            var user = dbSession.From<User>().Where(u => u.UserName == userName).First();
            user.Attach(EntityState.Modified);
            user.Password = passwordEnc;
            return dbSession.Save(user) > 0;
        }

        public bool UpdateUser(int id, string realName, string email, int orgId)
        {
            var user = dbSession.From<User>().Where(u => u.Id == id).First();
            user.Attach(EntityState.Modified);
            user.Email = email;
            user.OrgId = orgId;
            return dbSession.Save(user) > 0;
        }


        public bool DeleteUser(int id)
        {
            var user = dbSession.From<User>().Where(u => u.Id == id).First();
            return dbSession.Delete(user) > 0;
        }


        public IEnumerable<ViewUserEntity> List(int orgId)
        {
            var sql = dbSession.From<ViewUser>();

            sql.Where(user => user.OrgId == orgId);

            var userList = sql.ToList();
            return userList.Select(AutoMapper.Mapper.Map<ViewUserEntity>).ToList();
        }
    }
}
